package router

import (
	"gin-ranking/api/auth/controller"
	"gin-ranking/api/auth/dao"
	"gin-ranking/common/config"
	"gin-ranking/common/result"
	"gin-ranking/common/util"
	"gin-ranking/pkg/logs"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"runtime/debug"
	"strings"
)

// Core 解决跨域问题
func Core() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token,Authorization,Token")
		c.Header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS")
		c.Header("Access-Control-Expose-Headers", "Content-Length,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Content-Type")
		c.Header("Access-Control-Allow-Credentials", "True")
		//放行索引options
		if method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
		}
		//处理请求
		c.Next()
	}
}

// Recover 异常处理方法里面panic
func Recover(c *gin.Context) {
	defer func() {
		if r := recover(); r != nil {
			//打印错误堆栈信息
			log.Printf("panic: %v\n", r)
			debug.PrintStack()
			c.JSON(http.StatusOK, r)
			//终止后续接口调用，不加的话recover到异常后，还会继续执行接口里后续代码
			c.Abort()
		}
	}()
	//加载完 defer recover，继续后续接口调用
	c.Next()
}

// ValidateToken 验证token
func ValidateToken(c *gin.Context, token string) {

	token = strings.ReplaceAll(token, config.HeaderSignTokenStr, "")
	// 判断用户是否存在
	userSessionVo := dao.UserSessionDao{}.GetByToken(token)
	if len(userSessionVo.UserId) < 1 {
		c.JSON(http.StatusOK, result.FailEnum(result.CodeMsg402))
		c.Abort()
		return
	}
	between := util.Between(util.CurrentTime(), userSessionVo.ExpiresTime.Time, util.Second)
	if between >= 0 {
		c.JSON(http.StatusOK, result.FailEnum(result.CodeMsg403))
		c.Abort()
		return
	}
}

// TokenInterceptor 自定义拦截器
func TokenInterceptor() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 创建一个字符串类型的集合
		stringSet := util.NewSet[string]()
		// 向集合中添加元素
		stringSet.Add("/user/login")
		stringSet.Add("/user/register")

		if stringSet.Contains(c.Request.RequestURI) {
			c.Next()
			return
		}

		// 校验token
		header := c.Request.Header
		tokenStr := header.Get(config.HeaderSignToken)
		if len(tokenStr) < 1 {
			c.JSON(http.StatusOK, result.FailEnum(result.CodeMsg401))
			c.Abort()
			return
		}

		ValidateToken(c, tokenStr)
		// 调用下一个拦截器或处理器
		c.Next()
	}
}

func Router() *gin.Engine {
	r := gin.Default()
	// 全局使用自定义拦截器
	r.Use(TokenInterceptor())
	//r.Use(gin.LoggerWithConfig(logger.LoggerToFile()))
	r.Use(logs.Logger())
	r.Use(Core()) //
	r.Use(gin.Recovery())

	//r.Use(logger.Recover)
	r.Use(Recover)

	// 用户管理
	user := r.Group("user")
	{
		user.POST("register", TokenInterceptor(), controller.UserController{}.Register)
		user.POST("login", controller.UserController{}.Login)
		user.GET("info/:id", controller.UserController{}.QueryById)
		user.POST("pageList", controller.UserController{}.QueryPageList)
		user.POST("list", controller.UserController{}.QueryList)
		user.POST("add", controller.UserController{}.Add)
		user.POST("edit", controller.UserController{}.Edit)
		user.DELETE("delete/:ids", controller.UserController{}.DeleteByIds)
	}

	// 订单管理
	order := r.Group("order")
	{
		order.GET("info", controller.OrderController{}.OrderInfo)
		order.GET("pageList", controller.OrderController{}.OrderPageList)
		order.GET("list", controller.OrderController{}.OrderList)
		order.POST("add", controller.OrderController{}.OrderAdd)
		order.PUT("edit", controller.OrderController{}.OrderEdit)
		order.DELETE("delete", controller.OrderController{}.OrderDelete)
	}

	return r

}
